<script setup lang="ts">
import { ref, reactive, onMounted, h, nextTick, computed } from "vue";
import { DynamicTable } from "@/components/DynamicTable";
import { TableColumn } from "@/components/DynamicTable/types";
import DynamicForm from "@/components/DynamicForm/index.vue";
import type { DynamicFormInstance } from "@/components/DynamicForm/types";
import { FormItemConfig } from "@/components/DynamicForm/types";
import {
  ElMessage,
  ElMessageBox,
  ElTag,
  ElButton,
  ElDialog,
  ElDescriptions,
  ElDescriptionsItem,
  ElCard,
  ElDatePicker,
} from "element-plus";
import {
  Refresh,
  Edit,
  View,
  Delete,
  Plus,
} from "@element-plus/icons-vue";
import {
  getFalsePositiveList,
  markFalsePositive,
  revokeFalsePositive,
  updateFalsePositive,
} from "../servers";
const loading = ref(false);
const falsePositiveList = ref<any[]>([]);
const total = ref(0);
const page = ref(1);
const pageSize = ref(20);
const selectedFalsePositive = ref<any>(null);
const formRef = ref<DynamicFormInstance>();
const markFormRef = ref<DynamicFormInstance>();

const showDetailDialog = ref(false);
const showEditDialog = ref(false);
const showMarkDialog = ref(false);
const isEdit = ref(false);

// 搜索表单数据
const searchFormData = reactive({
  asset_ip: "",
  dimension_code: "",
  marked_by: "",
  dateRange: [] as any[],
});

// 标记误报表单数据
const markFormData = reactive({
  asset_ip: "",
  dimension_code: "",
  false_positive_reason: "",
  evidence: "",
  handling_method: "exclude_from_score" as
    | "exclude_from_score"
    | "adjust_score"
    | "mark_only",
  adjustment_value: 0,
  recalculate: true,
});

// 编辑表单数据
const editFormData = reactive({
  id: 0,
  false_positive_reason: "",
  evidence: "",
  handling_method: "exclude_from_score" as
    | "exclude_from_score"
    | "adjust_score"
    | "mark_only",
  adjustment_value: 0,
});

// 统计信息
const statistics = ref({
  total_count: 0,
  week_new: 0,
  exclude_count: 0,
  adjust_count: 0,
});

// 表格列配置
const columns = ref<TableColumn[]>([
  {
    label: "IP地址",
    prop: "asset_ip",
    minWidth: 150,
    show: true,
  },
  {
    label: "维度",
    prop: "dimension_name",
    minWidth: 120,
    show: true,
    render: (row) => {
      const dimensionMap: Record<string, string> = {
        vulnerability_risk: "漏洞风险",
        high_risk_port: "高危端口",
        compliance_status: "合规状态",
        local_remote_diff: "本地远程差异",
        malicious_outbound: "恶意外联",
        domain_weight: "资产重要性",
      };
      return h(
        ElTag,
        { type: "info", size: "small" },
        dimensionMap[row.dimension_code] || row.dimension_code
      );
    },
  },
  {
    label: "处理方式",
    prop: "handling_method",
    width: 120,
    show: true,
    render: (row) => {
      const methodMap: Record<string, { text: string; type: string }> = {
        exclude_from_score: { text: "排除", type: "success" },
        adjust_score: {
          text: row.adjustment_value
            ? `调整(${row.adjustment_value > 0 ? "+" : ""}${row.adjustment_value})`
            : "调整",
          type: "warning",
        },
        mark_only: { text: "仅标记", type: "info" },
      };
      const method = methodMap[row.handling_method] || {
        text: row.handling_method,
        type: "info",
      };
      return h(ElTag, { type: method.type as any, size: "small" }, method.text);
    },
  },
  {
    label: "标记人",
    prop: "marked_by",
    width: 120,
    show: true,
  },
  {
    label: "标记时间",
    prop: "marked_at",
    width: 180,
    show: true,
  },
  {
    label: "误报原因",
    prop: "false_positive_reason",
    minWidth: 200,
    show: true,
    render: (row) => {
      const reason = row.false_positive_reason || "无";
      const displayReason =
        reason.length > 50 ? reason.substring(0, 50) + "..." : reason;
      return h(
        "span",
        {
          style: { color: "#606266", cursor: "pointer" },
          onClick: () => handleViewDetail(row),
          title: reason,
        },
        displayReason
      );
    },
  },
  {
    label: "状态",
    prop: "is_active",
    width: 100,
    show: true,
    render: (row) => {
      return h(
        ElTag,
        { type: row.is_active ? "success" : "info", size: "small" },
        row.is_active ? "生效中" : "已撤销"
      );
    },
  },
]);

// 搜索表单配置
const searchFormConfig = computed<FormItemConfig[]>(() => [
  {
    key: "asset_ip",
    name: "IP地址",
    type: "input",
    labelWidth: "100px",
    placeholder: "请输入IP地址",
  },
  {
    key: "dimension_code",
    name: "维度",
    type: "select",
    labelWidth: "100px",
    placeholder: "选择维度",
    params: {
      options: [
        { label: "全部", value: "" },
        { label: "漏洞风险", value: "vulnerability_risk" },
        { label: "高危端口", value: "high_risk_port" },
        { label: "合规状态", value: "compliance_status" },
        { label: "本地远程差异", value: "local_remote_diff" },
        { label: "恶意外联", value: "malicious_outbound" },
      ],
    },
  },
  {
    key: "marked_by",
    name: "标记人",
    type: "input",
    labelWidth: "100px",
    placeholder: "请输入标记人",
  },
]);

// 标记误报表单配置
const markFormConfig = computed<FormItemConfig[]>(() => [
  {
    key: "asset_ip",
    name: "资产IP",
    type: "input",
    labelWidth: "120px",
    placeholder: "请输入资产IP",
    rules: [{ required: true, message: "请输入资产IP" }],
  },
  {
    key: "dimension_code",
    name: "维度",
    type: "select",
    labelWidth: "120px",
    placeholder: "选择维度",
    rules: [{ required: true, message: "请选择维度" }],
    params: {
      options: [
        { label: "漏洞风险", value: "vulnerability_risk" },
        { label: "高危端口", value: "high_risk_port" },
        { label: "合规状态", value: "compliance_status" },
        { label: "本地远程差异", value: "local_remote_diff" },
        { label: "恶意外联", value: "malicious_outbound" },
      ],
    },
  },
  {
    key: "false_positive_reason",
    name: "误报原因",
    type: "textarea",
    labelWidth: "120px",
    placeholder: "请输入误报原因（必填）",
    rules: [{ required: true, message: "请输入误报原因" }],
    params: {
      rows: 3,
    },
  },
  {
    key: "evidence",
    name: "证据说明",
    type: "textarea",
    labelWidth: "120px",
    placeholder: "请输入证据说明（可选）",
    params: {
      rows: 3,
    },
  },
  {
    key: "handling_method",
    name: "处理方式",
    type: "radio",
    labelWidth: "120px",
    params: {
      options: [
        { label: "排除该维度评分", value: "exclude_from_score" },
        { label: "调整分数", value: "adjust_score" },
        { label: "仅标记", value: "mark_only" },
      ],
    },
  },
  {
    key: "adjustment_value",
    name: "调整值",
    type: "number",
    labelWidth: "120px",
    placeholder: "正数=增加,负数=减少",
    params: {
      min: -100,
      max: 100,
    },
    show: (formData) => formData.handling_method === "adjust_score",
    rules: (formData) => {
      if (formData.handling_method === "adjust_score") {
        return [{ required: true, message: "请输入调整值" }];
      }
      return [];
    },
  },
  {
    key: "recalculate",
    name: "立即重新评分",
    type: "switch",
    labelWidth: "120px",
    defaultValue: true,
  },
]);

// 编辑表单配置
const editFormConfig = computed<FormItemConfig[]>(() => [
  {
    key: "false_positive_reason",
    name: "误报原因",
    type: "textarea",
    labelWidth: "120px",
    placeholder: "请输入误报原因",
    rules: [{ required: true, message: "请输入误报原因" }],
    params: {
      rows: 3,
    },
  },
  {
    key: "evidence",
    name: "证据说明",
    type: "textarea",
    labelWidth: "120px",
    placeholder: "请输入证据说明",
    params: {
      rows: 3,
    },
  },
  {
    key: "handling_method",
    name: "处理方式",
    type: "radio",
    labelWidth: "120px",
    params: {
      options: [
        { label: "排除该维度评分", value: "exclude_from_score" },
        { label: "调整分数", value: "adjust_score" },
        { label: "仅标记", value: "mark_only" },
      ],
    },
  },
  {
    key: "adjustment_value",
    name: "调整值",
    type: "number",
    labelWidth: "120px",
    placeholder: "正数=增加,负数=减少",
    params: {
      min: -100,
      max: 100,
    },
    show: (formData) => formData.handling_method === "adjust_score",
    rules: (formData) => {
      if (formData.handling_method === "adjust_score") {
        return [{ required: true, message: "请输入调整值" }];
      }
      return [];
    },
  },
]);

// 获取误报列表
const fetchFalsePositiveList = async () => {
  loading.value = true;
  try {
    const params: any = {
      page: page.value,
      page_size: pageSize.value,
    };
    if (searchFormData.asset_ip) {
      params.asset_ip = searchFormData.asset_ip;
    }
    if (searchFormData.dimension_code) {
      params.dimension_code = searchFormData.dimension_code;
    }
    if (searchFormData.marked_by) {
      params.marked_by = searchFormData.marked_by;
    }
    if (searchFormData.dateRange && searchFormData.dateRange.length === 2) {
      const startDate = searchFormData.dateRange[0];
      const endDate = searchFormData.dateRange[1];
      if (startDate && endDate) {
        params.start_date =
          typeof startDate === "string"
            ? startDate
            : startDate.format("YYYY-MM-DD");
        params.end_date =
          typeof endDate === "string"
            ? endDate
            : endDate.format("YYYY-MM-DD");
      }
    }
    const { data } = await getFalsePositiveList(params);
    falsePositiveList.value = data.list || [];
    total.value = data.total || 0;
    // 更新统计信息
    if (data.statistics) {
      statistics.value = data.statistics;
    }
  } catch (error: any) {
    ElMessage.error(error.message || "获取误报列表失败");
  } finally {
    loading.value = false;
  }
};

// 搜索
const handleSearch = () => {
  page.value = 1;
  fetchFalsePositiveList();
};

// 重置搜索
const handleReset = () => {
  Object.assign(searchFormData, {
    asset_ip: "",
    dimension_code: "",
    marked_by: "",
    dateRange: [],
  });
  handleSearch();
};

// 查看详情
const handleViewDetail = (row: any) => {
  selectedFalsePositive.value = row;
  showDetailDialog.value = true;
};

// 标记误报
const handleMark = () => {
  Object.assign(markFormData, {
    asset_ip: "",
    dimension_code: "",
    false_positive_reason: "",
    evidence: "",
    handling_method: "exclude_from_score",
    adjustment_value: 0,
    recalculate: true,
  });
  showMarkDialog.value = true;
  nextTick(() => {
    markFormRef.value?.resetFields();
  });
};

// 提交标记误报
const handleSubmitMark = async (values: any) => {
  try {
    await markFalsePositive(values);
    ElMessage.success("标记误报成功");
    showMarkDialog.value = false;
    fetchFalsePositiveList();
  } catch (error: any) {
    ElMessage.error(error.message || "标记误报失败");
  }
};

// 编辑误报
const handleEdit = (row: any) => {
  isEdit.value = true;
  Object.assign(editFormData, {
    id: row.id,
    false_positive_reason: row.false_positive_reason || "",
    evidence: row.evidence || "",
    handling_method: row.handling_method || "exclude_from_score",
    adjustment_value: row.adjustment_value || 0,
  });
  showEditDialog.value = true;
  nextTick(() => {
    formRef.value?.resetFields();
  });
};

// 提交编辑
const handleSubmitEdit = async (values: any) => {
  try {
    await updateFalsePositive({
      id: editFormData.id,
      ...values,
    });
    ElMessage.success("更新误报成功");
    showEditDialog.value = false;
    fetchFalsePositiveList();
  } catch (error: any) {
    ElMessage.error(error.message || "更新误报失败");
  }
};

// 撤销误报
const handleRevoke = async (row: any) => {
  try {
    await ElMessageBox.confirm(
      `确定要撤销IP "${row.asset_ip}" 的误报标记吗？撤销后将重新参与评分。`,
      "确认撤销",
      {
        type: "warning",
      }
    );
    await revokeFalsePositive({ id: row.id });
    ElMessage.success("撤销成功");
    fetchFalsePositiveList();
  } catch (error: any) {
    if (error !== "cancel") {
      ElMessage.error(error.message || "撤销失败");
    }
  }
};

// 删除误报
const handleDelete = async (row: any) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除IP "${row.asset_ip}" 的误报记录吗？此操作不可恢复。`,
      "确认删除",
      {
        type: "warning",
      }
    );
    // TODO: 如果有删除接口，调用删除接口
    ElMessage.info("删除功能开发中");
  } catch (error: any) {
    if (error !== "cancel") {
      ElMessage.error(error.message || "删除失败");
    }
  }
};

// 分页改变
const handlePageChange = (newPage: number) => {
  page.value = newPage;
  fetchFalsePositiveList();
};

// 每页条数改变
const handleSizeChange = (newSize: number) => {
  pageSize.value = newSize;
  page.value = 1;
  fetchFalsePositiveList();
};

onMounted(() => {
  fetchFalsePositiveList();
});
</script>

<template>
  <div>
    <!-- 统计信息卡片 -->
    <el-card shadow="never">
      <div style="display: flex; gap: 24px; flex-wrap: wrap">
        <div style="flex: 1; min-width: 150px">
          <div style="color: #909399; font-size: 14px; margin-bottom: 8px">
            总标记数
          </div>
          <div style="font-size: 24px; font-weight: bold; color: #303133">
            {{ statistics.total_count }}
          </div>
        </div>
        <div style="flex: 1; min-width: 150px">
          <div style="color: #909399; font-size: 14px; margin-bottom: 8px">
            本周新增
          </div>
          <div style="font-size: 24px; font-weight: bold; color: #67c23a">
            {{ statistics.week_new }}
          </div>
        </div>
        <div style="flex: 1; min-width: 150px">
          <div style="color: #909399; font-size: 14px; margin-bottom: 8px">
            排除处理
          </div>
          <div style="font-size: 24px; font-weight: bold; color: #409eff">
            {{ statistics.exclude_count }}
          </div>
        </div>
        <div style="flex: 1; min-width: 150px">
          <div style="color: #909399; font-size: 14px; margin-bottom: 8px">
            调整分数
          </div>
          <div style="font-size: 24px; font-weight: bold; color: #e6a23c">
            {{ statistics.adjust_count }}
          </div>
        </div>
      </div>
    </el-card>

    <div style="height: 10px"></div>

    <!-- 搜索表单 -->
    <el-card shadow="never">
      <DynamicForm
        v-model="searchFormData"
        :form-config="searchFormConfig"
        :gutter="16"
        inline
      >
        <template #after>
          <el-form-item label="时间范围">
            <el-date-picker
              v-model="searchFormData.dateRange"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              style="width: 300px"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch">搜索</el-button>
            <el-button @click="handleReset">重置</el-button>
          </el-form-item>
        </template>
      </DynamicForm>
    </el-card>

    <div style="height: 10px"></div>

    <!-- 误报列表 -->
    <el-card>
      <DynamicTable
        :columns="columns"
        :data="falsePositiveList"
        :loading="loading"
        :total="total"
        :page="page"
        :page-size="pageSize"
        @page-change="handlePageChange"
        @size-change="handleSizeChange"
      >
        <template #toolbar-left>
          <el-button type="primary" :icon="Plus" @click="handleMark">
            标记误报
          </el-button>
          <el-button
            type="info"
            :icon="Refresh"
            @click="fetchFalsePositiveList"
            :loading="loading"
          >
            刷新
          </el-button>
        </template>

        <template #action="{ row }">
          <el-button
            type="primary"
            size="small"
            :icon="View"
            @click="handleViewDetail(row)"
          >
            详情
          </el-button>
          <el-button
            v-if="row.is_active"
            type="warning"
            size="small"
            :icon="Edit"
            @click="handleEdit(row)"
          >
            编辑
          </el-button>
          <el-button
            v-if="row.is_active"
            type="danger"
            size="small"
            :icon="Delete"
            @click="handleRevoke(row)"
          >
            撤销
          </el-button>
        </template>
      </DynamicTable>
    </el-card>

    <!-- 详情对话框 -->
    <el-dialog
      v-model="showDetailDialog"
      :title="
        selectedFalsePositive
          ? `误报详情 - ${selectedFalsePositive.asset_ip}`
          : '误报详情'
      "
      width="700px"
      destroy-on-close
    >
      <div v-if="selectedFalsePositive">
        <el-descriptions :column="1" border>
          <el-descriptions-item label="资产IP">
            <span style="font-weight: bold">{{
              selectedFalsePositive.asset_ip
            }}</span>
          </el-descriptions-item>
          <el-descriptions-item label="维度">
            {{
              selectedFalsePositive.dimension_name ||
              selectedFalsePositive.dimension_code
            }}
          </el-descriptions-item>
          <el-descriptions-item label="处理方式">
            <el-tag
              :type="
                selectedFalsePositive.handling_method === 'exclude_from_score'
                  ? 'success'
                  : selectedFalsePositive.handling_method === 'adjust_score'
                  ? 'warning'
                  : 'info'
              "
            >
              {{
                selectedFalsePositive.handling_method === "exclude_from_score"
                  ? "排除该维度评分"
                  : selectedFalsePositive.handling_method === "adjust_score"
                  ? `调整分数(${
                      selectedFalsePositive.adjustment_value > 0 ? "+" : ""
                    }${selectedFalsePositive.adjustment_value})`
                  : "仅标记"
              }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="误报原因">
            <div style="white-space: pre-wrap; color: #606266">
              {{ selectedFalsePositive.false_positive_reason || "无" }}
            </div>
          </el-descriptions-item>
          <el-descriptions-item
            v-if="selectedFalsePositive.evidence"
            label="证据说明"
          >
            <div style="white-space: pre-wrap; color: #606266">
              {{ selectedFalsePositive.evidence }}
            </div>
          </el-descriptions-item>
          <el-descriptions-item label="标记人">
            {{ selectedFalsePositive.marked_by }}
          </el-descriptions-item>
          <el-descriptions-item label="标记时间">
            {{ selectedFalsePositive.marked_at }}
          </el-descriptions-item>
          <el-descriptions-item label="状态">
            <el-tag
              :type="selectedFalsePositive.is_active ? 'success' : 'info'"
            >
              {{ selectedFalsePositive.is_active ? "生效中" : "已撤销" }}
            </el-tag>
          </el-descriptions-item>
        </el-descriptions>
      </div>
    </el-dialog>

    <!-- 标记误报对话框 -->
    <el-dialog
      v-model="showMarkDialog"
      title="标记误报"
      width="700px"
      destroy-on-close
      @close="
        () => {
          showMarkDialog = false;
          markFormRef?.resetFields();
        }
      "
    >
      <DynamicForm
        ref="markFormRef"
        v-model="markFormData"
        :form-config="markFormConfig"
        :gutter="16"
        type="submit"
        @submit="handleSubmitMark"
        @cancel="
          () => {
            showMarkDialog = false;
            markFormRef?.resetFields();
          }
        "
      />
    </el-dialog>

    <!-- 编辑误报对话框 -->
    <el-dialog
      v-model="showEditDialog"
      title="编辑误报"
      width="700px"
      destroy-on-close
      @close="
        () => {
          showEditDialog = false;
          formRef?.resetFields();
        }
      "
    >
      <DynamicForm
        ref="formRef"
        v-model="editFormData"
        :form-config="editFormConfig"
        :gutter="16"
        type="submit"
        @submit="handleSubmitEdit"
        @cancel="
          () => {
            showEditDialog = false;
            formRef?.resetFields();
          }
        "
      />
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
:deep(.el-descriptions__label) {
  font-weight: 500;
}
</style>
